iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0
自我挑戰組

嘗試30天學「不」會Rust系列 第 11

[Rust] 常見集合 - 動態陣列 (vector)

  • 分享至 

  • xImage
  •  

環境

OS: Windows 10
Editor: Visual Studio Code
Rust version: 1.63.0

向量(vector)

建立

Rust的向量,是一個可以自動增長的陣列,連續的記憶體空間,建立方式如下:

// 建立一個i32的向量
let v: Vec<i32> = Vec::new();

注意!因為Vec是泛型的關係,所以宣告的時候需要指定型別,所以以下這個寫法是非法的:

let v = Vec::new(); // 錯誤!不知道是什麼型別的集合

當然,如果已經有初始值的話,compiler會幫你辨識出這個向量是甚麼型別的:

let v = vec![1, 3, 5, 7]; // Vec<i32>

注意vec![]!,先前使用println!()的時候也有這個符號,而這個符號表示Rust中的巨集(macro)。這個之後會介紹到。

取值

要取得向量中的值的話,有兩種方式:

// Use []
let one = &v[0];

// Use `get()`
let two = v.get(1);

使用[]會有潛在危險,如果索引(index)超出大小的話,沒辦法經過檢查,執行結果會直接出現exception:

let vec = vec![1, 3, 5, 7, 9];
let x = &vec[5];
println!("x is {}", x);

/*
 * output:
 *    thread 'main' panicked at 'index out of bounds: the len is 5 but the index is 5', src\main.rs:4:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\basic.exe` (exit code: 101)
 */

使用get的話,回傳的Option<T>,這可以讓我們處理當取不到值的情況:

let vec = vec![1, 3, 5, 7, 9];
let x = vec.get(5);
match x {
    Some(val) => println!("x is {}", val),
    None => println!("Value not found"),
}

/*
 * output: 
 *      Value not found
 */

加入與刪除

再來是一些常用最常用的加入刪除

let mut vec = vec![1, 3, 5, 7, 9]; // 記得要變成"可變"

// 加入
vec.push(11);

// 刪除
let last = vec.pop(); // 這個回傳`Option<T>`
match last {
    Some(val) => println!("x is {}", val),
    None => println!("Value not found"),
}

由於Vec<T>的底層實作是陣列,所以沒有實作插入(insert)或是push_front 之類的,這不合效益,如果從頭(head)加入好了,這會需要把整個陣列重新編排,如果有這種需求,應該要取使用Deque之類的資料結構。

遍歷

尋訪的會之前其實就有試過,有幾種不同的方法

let vec = vec![1, 3, 5, 7, 9];

// 使用index
for index in 0..vec.len() {
    println!("{}", vec[index]);
}

// 遍歷
for v in &vec {
    println!("{}", v);
}

// 同時拿出index與資料
for (index, item) in vec.iter().enumerate() {
    println!("{} : {}", index, item);
}

Reference


上一篇
Option型別
下一篇
[Rust] 常用集合-字串 (string)
系列文
嘗試30天學「不」會Rust18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言